package com.niannian.util.network;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import com.niannian.db.MyDBUser;
import com.niannian.util.ErrorCode;
import com.niannian.util.UserInfoManager;
import android.util.Log;

public class HttpService {

	private static HttpClient httpClient = null;

	/**
	 * 表单验证
	 */
	private static final String tokenName = "X-CSRFTOKEN";
	/**
	 * 帐号登录
	 */
	private static final String tokenName2 = "Authorization";
	/**
	 * 当前链接的字符编码
	 */
	protected String charset = HTTP.UTF_8;
	/**
	 * 连接请求的超时时间
	 */
	protected int connectionTimeout = 5000;

	/**
	 * 读取远程数据的超时时间
	 */
	protected int soTimeout = 10000;
	/**
	 * HTTP 请求的配置参数
	 */
	protected HttpParams httpParameters = null;
	private static MyDBUser userInfoManager = UserInfoManager.getUserInfoInstance();

	public HttpService() {

		// 配置 HTTP 请求参数
		this.httpParameters = new BasicHttpParams();
		this.httpParameters.setParameter("charset", this.charset);
		// 设置 连接请求超时时间
		HttpConnectionParams.setConnectionTimeout(this.httpParameters, this.connectionTimeout);
		// 设置 socket 读取超时时间
		HttpConnectionParams.setSoTimeout(this.httpParameters, this.soTimeout);
		// 开启一个客户端 HTTP 请求
		httpClient = new DefaultHttpClient(this.httpParameters);
	}

	// public HttpService() {
	// HttpParams httpParams = new BasicHttpParams();
	// httpParams.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 20);
	// SchemeRegistry schreg = new SchemeRegistry();
	// schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(),
	// 88));
	// ThreadSafeClientConnManager connManager = new
	// ThreadSafeClientConnManager(httpParams, schreg);
	// httpClient = new DefaultHttpClient(connManager, httpParams);
	//
	// }

	// private static final String baseUri = "http://api.activity.me/v1/auth/";

	public HttpResponse sendPostRequest(List<NameValuePair> params, String uri) {
		try {
			UrlEncodedFormEntity entity = null;
			HttpPost httpPost = new HttpPost(uri);
			if (params != null && !params.isEmpty()) {
				entity = new UrlEncodedFormEntity(params, charset);
				httpPost.setEntity(entity);
			}
			httpPost.addHeader(tokenName, userInfoManager.token);
			httpPost.addHeader(tokenName2, userInfoManager.token2);
			HttpResponse response = httpClient.execute(httpPost);
			return response;

		} catch (Exception e) {
			Log.e("activity", "Exception catched in HttpService: " + e.toString());
			return null;
		}
	}

	/**
	 * 发送带文件的post请求
	 * 
	 * @param textParams
	 *            ： 普通参数
	 * @param fileParams
	 *            ： 文件参数 {Name：Value} Name: 参数名， Value： 文件路径
	 * @param uri
	 * @return
	 */
	public HttpResponse sendPostRequest(List<NameValuePair> textParams, List<NameValuePair> fileParams, String uri) {
		String CHARSET = HTTP.UTF_8;
		ContentType TEXT_PLAIN = ContentType.create("text/plain", Charset.forName(CHARSET));

		try {
			MultipartEntityBuilder multiEntityBuilder = MultipartEntityBuilder.create();
			multiEntityBuilder.setCharset(Charset.forName(this.charset));
			// set the plain text params
			if (textParams != null && !textParams.isEmpty()) {
				for (NameValuePair textParam : textParams) {
					multiEntityBuilder.addTextBody(textParam.getName(), textParam.getValue(), TEXT_PLAIN);
				}
			}

			if (fileParams != null && !fileParams.isEmpty()) {
				Log.i("activity", "file operate1");
				for (NameValuePair fileParam : fileParams) {
					Log.i("activity", "file operates");
					File file = new File(fileParam.getValue());

					Log.i("activity", file.toString());
					multiEntityBuilder.addBinaryBody(fileParam.getName(), file);
					// multiEntityBuilder.setMode(mode)

				}
				Log.i("activity", "file operate2");
			}
			HttpEntity entity = multiEntityBuilder.build();

			// Log.i("activity", "mult" + EntityUtils.toString(entity));
			HttpPost httpPost = new HttpPost(uri);
			httpPost.addHeader(tokenName, userInfoManager.token);
			httpPost.addHeader(tokenName2, userInfoManager.token2);
			// httpPost.setHeader("Content-Type",
			// "application/x-www-form-urlencoded");
			httpPost.setEntity(entity);

			HttpResponse response = httpClient.execute(httpPost);

			return response;
		} catch (Exception e) {
			Log.e("activity", "Exception catched: " + e.toString());
		}
		;

		return null;
	}

	public HttpResponse sendGetRequest(List<NameValuePair> params, String uri) {
		try {
			String paramsstring = "";
			if (params != null && !params.isEmpty()) {

				for (int i = 0; i < params.size(); i++) {
					NameValuePair param = params.get(i);
					if (i == 0) {
						paramsstring = paramsstring + param.getName() + "=" + param.getValue();
					} else {
						paramsstring = paramsstring + "&" + param.getName() + "=" + param.getValue();
					}

				}
				uri = uri + "?" + paramsstring;
			}
			uri = uri.replaceAll(" ", "%20");
			HttpGet httpGet = new HttpGet(uri);
			httpGet.addHeader(tokenName, userInfoManager.token);
			httpGet.addHeader(tokenName2, userInfoManager.token2);
			HttpResponse response = httpClient.execute(httpGet);

			return response;
		} catch (Exception e) {
			Log.e("activity", "Exception catched : " + e.toString());
		}

		return null;
	}

	public HttpResponse sendPutRequest(List<NameValuePair> params, String uri) {
		try {
			UrlEncodedFormEntity entity = null;
			HttpPut httpPut = new HttpPut(uri);
			if (params != null && !params.isEmpty()) {
				entity = new UrlEncodedFormEntity(params, this.charset);

				httpPut.setEntity(entity);
			}
			httpPut.addHeader(tokenName, userInfoManager.token);
			httpPut.addHeader(tokenName2, userInfoManager.token2);
			HttpResponse response = httpClient.execute(httpPut);
			return response;

		} catch (Exception e) {
			Log.e("activity", "Exception catched: " + e.toString());
		}
		return null;
	}

	/**
	 * Put方式发送带文件的请求
	 * 
	 * @param textParams
	 *            : 普通参数
	 * @param fileParams
	 *            ： 文件参数
	 * @param uri
	 * @return
	 */
	public HttpResponse sendPutRequest(List<NameValuePair> textParams, List<NameValuePair> fileParams, String uri) {
		String CHARSET = HTTP.UTF_8;
		ContentType TEXT_PLAIN = ContentType.create("text/plain", Charset.forName(CHARSET));

		try {
			MultipartEntityBuilder multiEntityBuilder = MultipartEntityBuilder.create();
			multiEntityBuilder.setCharset(Charset.forName(this.charset));

			// set the plain text params
			if (textParams != null && !textParams.isEmpty()) {
				for (NameValuePair textParam : textParams) {
					multiEntityBuilder.addTextBody(textParam.getName(), textParam.getValue(), TEXT_PLAIN);
				}
			}

			if (fileParams != null && !fileParams.isEmpty()) {
				Log.i("activity", "file operate1...................................");
				for (NameValuePair fileParam : fileParams) {
					Log.i("activity", "file operates");
					File file = new File(fileParam.getValue());
					if (file.exists()) {
						Log.i("activity", file.toString());
						multiEntityBuilder.addBinaryBody(fileParam.getName(), file);

					}

				}
				Log.i("activity", "file operate2..................................");
			}
			HttpEntity entity = multiEntityBuilder.build();

			// Log.i("activity", "mult" + EntityUtils.toString(entity));
			HttpPut httpPut = new HttpPut(uri);
			httpPut.addHeader(tokenName, userInfoManager.token);
			httpPut.addHeader(tokenName2, userInfoManager.token2);
			httpPut.setEntity(entity);
			HttpResponse response = httpClient.execute(httpPut);

			return response;
		} catch (Exception e) {
			Log.e("activity", "Exception catched: " + e.toString());
		}
		;

		return null;
	}

	public HttpResponse sendDeleteRequest(String uri) {
		try {
			HttpDelete httpDelete = new HttpDelete(uri);
			httpDelete.addHeader(tokenName, userInfoManager.token);
			httpDelete.addHeader(tokenName2, userInfoManager.token2);
			return httpClient.execute(httpDelete);
		} catch (Exception e) {
			Log.e("activity", "Exception catched: " + e.toString());
		}
		return null;
	}

	public HttpResponse sendDeleteRequest(List<NameValuePair> params, String uri) {
		try {
			String paramsstring = "";
			if (params != null && !params.isEmpty()) {

				for (int i = 0; i < params.size(); i++) {
					NameValuePair param = params.get(i);
					if (i == 0) {
						paramsstring = paramsstring + param.getName() + "=" + param.getValue();
					} else {
						paramsstring = paramsstring + "&" + param.getName() + "=" + param.getValue();
					}

				}
				uri = uri + "?" + paramsstring;
			}

			HttpDelete httpDelete = new HttpDelete(uri);
			httpDelete.addHeader(tokenName, userInfoManager.token);
			httpDelete.addHeader(tokenName2, userInfoManager.token2);
			HttpResponse response = httpClient.execute(httpDelete);
			return response;
		} catch (Exception e) {
			Log.e("activity", "Exception catched : " + e.toString());
		}

		return null;
	}

	public String downLoadFile(String uri, String locaFilePath) {
		OutputStream outputStream = null;
		try {
			File file = new File(locaFilePath);
			if (file.exists()) {
				// TODO
				Log.i("activity", locaFilePath + " exists !");
				return "{\"code\":" + ErrorCode.OK + "}";
			} else {
				URL url = new URL(uri);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				InputStream inputStream = conn.getInputStream();
				// Notice: SD目录+路径+文件名，确保中间的路径存在，不存在新建目录
				Log.i("activity", locaFilePath + "  不存在 !");
				file.createNewFile();
				Log.i("activity", locaFilePath + "  创建成功 !");
				outputStream = new FileOutputStream(file);

				byte[] buffer = new byte[1024];
				int len = -1;
				while ((len = inputStream.read(buffer)) != -1) {
					outputStream.write(buffer, 0, len);
				}
				outputStream.flush();
				Log.i("activity", "Done downloading!");
				return "{\"code\":" + ErrorCode.OK + "}";
			}

		} catch (Exception e) {

			Log.e("activity", "fail downloading!" + e.toString());
			e.printStackTrace();
			return "{\"code\":" + ErrorCode.FAILED + "}";
		} finally {
			try {
				if (outputStream != null)
					outputStream.close();
				outputStream = null;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	// make sure the "csrftoken" do exists in cookies
	public boolean setXToken() {
		List<Cookie> cookies = ((AbstractHttpClient) httpClient).getCookieStore().getCookies();
		for (Cookie cookie : cookies) {
			if (cookie.getName().equals("csrftoken")) { // csrftoken exists in
				// cookie
				try {
					userInfoManager.token = cookie.getValue();
					userInfoManager.updateDBUser();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Log.i("activity", "Token: " + cookie.getValue());
				return true;
			}
		}
		return false;
	}

	// make sure the "Authorization" do exists in cookies
	public boolean setXToken2() {
		List<Cookie> cookies = ((AbstractHttpClient) httpClient).getCookieStore().getCookies();
		for (Cookie cookie : cookies) {
			if (cookie.getName().equals("authtoken")) { // authtoken exists
														// in // cookie
				try {
					userInfoManager.token2 = "Token " + cookie.getValue();
					userInfoManager.updateDBUser();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Log.i("activity", "Token2: " + cookie.getValue());
				return true;
			}
		}
		return false;
	}

}
